﻿using System;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.Windows;
using Newtonsoft.Json.Linq;
using RestSharp;

namespace GTasksPlus.Code
{
    public class OAuthHelper
    {
        public static Uri GetLoginUrl()
        {
            return new Uri(string.Format("{0}?client_id={1}&redirect_uri={2}&scope={3}&response_type=code",
                                         GTasksSettings.OAuthUrl,
                                         GTasksSettings.ClientId, GTasksSettings.RedirectUri, GTasksSettings.Scope));
        }

        private static string GetRequestAccessTokenPostBody(bool isRefresh)
        {
            var body = String.Format("client_id={0}&client_secret={1}&", GTasksSettings.ClientId,
                                     GTasksSettings.ClientSecret);
            return isRefresh ? String.Format(body + "refresh_token={0}&grant_type=refresh_token", GTasksSettings.RefreshToken) : String.Format(body + "code={0}&redirect_uri={1}&grant_type=authorization_code", GTasksSettings.TokenCode, GTasksSettings.RedirectUri);
        }

        public static void GetRequestTokenQuery(bool isRefresh, Action<List<object>> callback)
        {
            var postBody = GetRequestAccessTokenPostBody(isRefresh);
            var client = new RestClient { Timeout = GTasksSettings.RequestTimeout };
            var request = new RestRequest(Method.POST)
            {
                Resource = GTasksSettings.OAuthTokenUrl
            };
            request.AddParameter("application/x-www-form-urlencoded", postBody, ParameterType.RequestBody);
            client.ExecuteAsync(request, response =>
            {
                try
                {
                    var o = JObject.Parse(response.Content);
                    GTasksSettings.AccessToken = (string)o.SelectToken("access_token");
                    GTasksSettings.TokenExpiry = (int)o.SelectToken("expires_in");
                    JToken j;
                    if (o.TryGetValue("refresh_token", out j))
                        GTasksSettings.RefreshToken = j.Value<string>();
                    if (callback != null)
                        callback(new List<object> {GTasksSettings.AccessToken});
                }
                catch (Exception e)
                {
                    MessageBox.Show("Some error while trying to retrieve OAuth token code.\n\n" + e.Message);
                }
            });
        }

        public static void RefreshTokenCode(Action<List<object>> callback)
        {
            var settings = IsolatedStorageSettings.ApplicationSettings;
            if (settings.Contains("Timestamp"))
            {
                var secondsElapsed = TimeSpan.FromTicks(DateTime.Now.Ticks).TotalSeconds - (double)settings["Timestamp"];
                if (secondsElapsed > GTasksSettings.TokenExpiry)
                    GetRequestTokenQuery(true, callback);
                else
                    callback(new List<object> {new List<string>()});
            }
        }
    }
}
